home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / bnchutil.arc / AW.C < prev    next >
Text File  |  1991-04-30  |  24KB  |  766 lines

  1. /***************************************************************
  2. *                                   *
  3. *       WHERE                           *
  4. *                                   *
  5. * Where is a program to locate files on the PC hard disk.      *
  6. * It requires DOS 2.x or 3.x.                       *
  7. *                                   *
  8. * The command line syntax is:                       *
  9. * where [starting directory]filename.ext               *
  10. *                                   *
  11. * Written by Mark S. Ackerman                       *
  12. * PROGRAM IS WRITTEN IN MARK WILLIAMS  M W C 8 6  LANGUAGE     *
  13. * Copyright 1984, 1985 by Mark S. Ackerman.  Permission is     *
  14. * granted for unlimited copies if not sold or otherwise        *
  15. * exchanged for gain.                           *
  16. *  PUBLISHED IN PC TECH JOURNAL - OCT '85 - VOL 3, NO. 10      *
  17. *                                   *
  18. *  MODIFIED FOR LATTICE C VER 2.15 BY JOHN TEICHERT NOV 85     *
  19. *     Names shortened to 8 significant characters.           *
  20. *     Elimination of PTOREG() function                   *
  21. *     flag86 defined to return flags from intdosx()           *
  22. *     Use segread to set up regs for intdosx() function.       *
  23. *     Program modified to look for drive designator with colon.*
  24. *     DATE structure defined with bits high order to low order.*
  25. *     intrpt.h replaced with dos.h header file               *
  26. *     rindex() function replaced with strrchr() function.      *
  27. *                                   *
  28. *  MODIFIED FOR MICROSOFT V3 BY JOHN TEICHERT JAN 86.           *
  29. *     flag86 REDEFINED to dos_result for  intdosx() ax reg     *
  30. *     modified to use flag in REGS structure.               *
  31. *     DATE structure defined with bits low order to high order.*
  32. *     _stack will not produce large stack in ver 3.0 must use  *
  33. *         link option or exemod program.               *
  34. *                                   *
  35. *   Added Code And Became ANYWHERE  JOHN TEICHERT FEB 86       *
  36. *                                   *
  37. *    Taking advantange of V3 access to the environment      *
  38. *    string we set up the following.                *
  39. *                                   *
  40. *    1. An Environment String indicating what disk drives   *
  41. *       you want ANYWHERE to search as follows:           *
  42. *                                   *
  43. *       AWDISKS=d:[;d:[;d:;...d:]]                   *
  44. *                                   *
  45. *          where d: is the drive specifier for one or more  *
  46. *          fixed disk(s).                       *
  47. *                                   *
  48. *          drive specifiers are searched in the order they  *
  49. *          are entered.                       *
  50. *                                   *
  51. *    2. The user can specify the environment string with    *
  52. *       the use of the set command in the autoexec.bat file.*
  53. *       As an example:                       *
  54. *                                   *
  55. *        set awdisks=c:;e:;d:                   *
  56. *                                   *
  57. *       would be placed into the autoexec.bat file.           *
  58. *                                   *
  59. *    With this modification the user has extended directory *
  60. *    capabilities by automatically searching all disk drives*
  61. *    listed in the environment string or isolated to a      *
  62. *    single drive by placing a drive specifier in the       *
  63. *    command line argument string.                   *
  64. *                                   *
  65. *    Be sure to use the /stack option on the link with      *
  66. *    Microsoft V3 C compiler or stack problems will result  *
  67. *    if many subdirectories.  8K seems to work well.        *
  68. *                                   *
  69. ***************************************************************/
  70.  
  71.  
  72. /***************************************************************
  73. * The C header files                           *
  74. * These identify library routines like printf() and int86x()  *
  75. ***************************************************************/
  76.  
  77. #include <stdio.h>   /* standard i/o                  */
  78. #include <dos.h>     /* functions for DOS interrupt calls     */
  79.  
  80. /***************************************************************
  81. * Structure for MS-DOS date and time fields               *
  82. * See pages 4-6 and 4-7 of the DOS 2.1 technical           *
  83. * reference manual for more information                *
  84. * This structure is used in the next structure definition      *
  85. ***************************************************************/
  86.  
  87. struct msdos_date
  88.     {
  89.     unsigned ms_sec    : 5; /* time in 2 sec. int (5 bits)*/
  90.     unsigned ms_min    : 6; /* minutes (6 bits)          */
  91.     unsigned ms_hour   : 5; /* hours (5 bits)          */
  92.     unsigned ms_day    : 5; /* day of month (5 bits)      */
  93.     unsigned ms_month  : 4; /* month (4 bits)          */
  94.     unsigned ms_year   : 7; /* year since 1980 (7 bits)   */
  95.     };
  96.  
  97. /***************************************************************
  98. * Definition of DOS Disk Transfer Area (DTA)               *
  99. ***************************************************************/
  100.  
  101. /***************************************************************
  102. * Structure filled in by MS-DOS for interrupt 21 calls           *
  103. * See page 5-46 of the DOS 2.1 technical reference           *
  104. * manual for more information                       *
  105. ***************************************************************/
  106.  
  107. struct DTA
  108.     {
  109.     char    DTA_dosinfo[21];       /* used by DOS        */
  110.     char    DTA_attr;           /* file attribute byte    */
  111.     struct msdos_date DTA_date;    /* date struct. as above */
  112.     long    DTA_size;           /* file size        */
  113.     char    DTA_filename[13];      /* file name (w/o path)    */
  114.     };
  115.  
  116.  
  117. /***************************************************************
  118. *        Definitions of constants               *
  119. ***************************************************************/
  120.  
  121. #define carry_set 0x0001 /* mask for flag register           */
  122.              /* for carry bit               */
  123. #define no_type   0x00     /* no bits set on file attribute byte */
  124. #define directory_type     0x10 /* directory file bit on file    */
  125.                   /* info word               */
  126.  
  127. #define no_more_files     18    /* DOS return code for        */
  128.                 /* no more files        */
  129.  
  130. #define end_of_string     '\0'   /* C uses a binary zero to      */
  131.                 /* signal end of string     */
  132.  
  133. #define backslash '\\'   /* the backslash character           */
  134. #define colon      ':'    /* Drive separator  JT 11/85           */
  135. #define semicolon ';'   /* Environment string drive separator   */
  136.  
  137. char *month[] = {
  138.         "Jan","Feb","Mar","Apr","May","Jun",
  139.         "Jul","Aug","Sep","Oct","Nov","Dec"
  140.         };
  141.  
  142. char *time_of_day[2] = {"AM","PM"};
  143.  
  144.  
  145. /***************************************************************
  146. *        Define the type "filename"                     *
  147. *            to be a string of 65 characters  -JT   *
  148. ***************************************************************/
  149.  
  150. typedef char filename[65];           /* Change to 65 -JT             */
  151.  
  152. /***************************************************************
  153. *                                   *
  154. * The following filename strings are used in the program:      *
  155. *                                   *
  156. *    chk_str         filename to be searched for    *
  157. *                filename in the command line)  *
  158. *    dir_string        directory name to be searched  *
  159. *    new_dstr        directory name to be searched  *
  160. *                  on next recursive call       *
  161. *    cur_str         temporary string for searching *
  162. *                  in a specific directory      *
  163. ***************************************************************/
  164.  
  165.  
  166. /***************************************************************
  167. * Definition of any forward-referenced functions           *
  168. ***************************************************************/
  169.  
  170. char *DATE();
  171.  
  172. /***************************************************************
  173. *        Global variables                   *
  174. ***************************************************************/
  175.  
  176. filename chk_str;            /* this string "remembers" user input */
  177. union    REGS    r8086;            /* structure to allow access to indiv.*/
  178.                     /*   registers for interrupts          */
  179. struct    SREGS    s8086;            /*   structure for segment registers  */
  180. char        date_str[40];        /* print output string for dates      */
  181. unsigned    dos_result;        /* Return code from DOS           */
  182.  
  183. /**
  184. *    FOLLOWING CODE COMMENTED OUT FOR V3.0 SINCE CAN'T FIND A WAY TO DO IT
  185. *    WITH A VARIABLE.
  186. **/
  187.  
  188. /*int          _stack = 8192;       Insure large stack to support */
  189. /*                       recursion in look routine     */
  190.  
  191. /***************************************************************
  192. *        MAIN() -- the beginning of the code           *
  193. ***************************************************************/
  194.  
  195. main( argc, argv, envp )
  196. int    argc;
  197. char    *argv[];
  198. char    *envp[];            /* Version 3 pointer to environ */
  199. {
  200. /**
  201. *    External    function
  202. **/
  203. char            *strrchr();    /* Lattice function which searches */
  204.                     /* for the last occurrance of the  */
  205.                     /* desired character           */
  206.  
  207. char            *strchr();    /* Lattice function which searches */
  208.                     /* for the first occurrance of the */
  209.                     /* desired character           */
  210.  
  211. filename           dir_string;    /* directory to be searched       */
  212.  
  213. char               *usr_file;    /* address of filename in       */
  214.                     /* command line argument       */
  215.                     /* (ie, the filename)           */
  216.  
  217. char *last_loc;             /* address of last backslash in    */
  218.                     /* command line argument       */
  219.  
  220. char *dos_parm;             /* address of               */
  221.                     /* command line argument       */
  222.  
  223. int  lst_dchr;                /* last character           */
  224.                     /* in directory string           */
  225.  
  226. /** added for ANYWHERE JT **/
  227. int            strcmpi();    /* Microsoft V3 function to do a     */
  228.                     /*   string compare without regard   */
  229.                     /*   to case.                 */
  230. void            strcat();    /* String concatenate function         */
  231. #define     MAXEDRV    16        /* Set max number of drives         */
  232. char            *strdup();    /* MSC string dup function         */
  233. char            *getcwd();    /* MSC ver3 function to return         */
  234.                     /* current working directory         */
  235. char            *envdup;    /* pointer to duplicate of env str   */
  236. char            *envdrv[MAXEDRV];   /* pointer to each drive         */
  237.                     /* in envdup                 */
  238. filename        env_dir_string; /* Environment directory string      */
  239. char            **cur_envp;    /* current environmnet array pointer */
  240. char            *env_stp;    /* Current environment string pointer*/
  241. char            *env_chp;    /* environment character pointer     */
  242. static    char        envid[]="AWDISK=";      /* Our environment string id */
  243. char            *envid_p;    /* current id string ptr         */
  244. filename        dos_cwd;    /* buffer to hold cur working dir    */
  245. int            env_cnt;    /* count of number of drives         */
  246. int            envd_len;    /* length of the environment string  */
  247. int            wi;        /* A working integer             */
  248. struct    {
  249.     unsigned    drive    : 1;    /* drive specifier found in com line */
  250.     unsigned    found    : 1;    /* environment contains AWDISK=      */
  251.     unsigned    srchcwd : 1;    /* Search for current work dir         */
  252.     unsigned    addcwd    : 1;    /* Add current working directory     */
  253.     } flag;
  254.  
  255. /********************************************************
  256. *    check number of incoming arguments        *
  257. *    if incorrect, write an error message        *
  258. ********************************************************/
  259.  
  260. if (argc != 2)
  261.     {
  262.     printf( "ERR  usage is:   AW    [starting directory]filename.ext\n\n");
  263.     printf( "Environment string is: AWDISK=d: [;d: [;....d:] ]\n");
  264.     return;
  265.     }
  266.  
  267. /**    Added for Lattice C Version 2.15 JT
  268. *    Initialize the segment structure for later dos interrupt calls.
  269. **/
  270.  
  271. segread( &s8086 );        /* initialize segments for interrupt calls */
  272. dos_result = 0;         /* init interrupt return variable MSCV3.   */
  273.  
  274. /**
  275. *    dos_parm is set to the first argument in the
  276. *    command line
  277. **/
  278.  
  279. dos_parm = *(++argv);
  280.  
  281. /**
  282. *    If a drive specifier is found we do not want to go through overhead
  283. *    of environment string search.        AW - JT
  284. *    If no drive specifier is found we will extract the drive of the
  285. *        current working directory to be added to the array of environment
  286. *        drives.
  287. **/
  288. flag.srchcwd = 1;            /* Init true until command line      */
  289.                     /*     option added.             */
  290. if ( strchr( dos_parm, colon ) )
  291.     {
  292.     flag.drive = 1;            /* Set drive specifier true         */
  293.     flag.found = 0;            /* Set environment found false         */
  294.     }
  295. else
  296.     {
  297.     /**
  298.     *    Drive flag is set to zero
  299.     *    If the search current working directory flag is true then:
  300.     *        Current working directory is obtained and the drive isolated from
  301.     *        from the directory string.
  302.     **/
  303.     flag.drive = 0;
  304.     if ( flag.srchcwd )
  305.     {
  306.     getcwd(dos_cwd,sizeof(dos_cwd)-1);
  307.     env_chp = strchr( dos_cwd, colon );
  308.     *++env_chp = end_of_string;
  309.     }
  310.     }
  311. /**
  312. *   We check to see if there was a drive specifier found.  If so we
  313. +    want to continue rather than check the environment string for the
  314. *    AWDISK= parameter
  315. **/
  316. if (flag.drive)
  317.     {
  318.     /**
  319.     *    There was a drive specifier so we zero the env_cnt variable
  320.     **/
  321.     env_cnt = 0;
  322.     }
  323. else
  324.     {
  325.     /**
  326.     *    The drive specifier was  found in the DOS command argument therefore
  327.     *        the environment strings will be searched for the AWDISK= parameter
  328.     **/
  329.     cur_envp = envp;            /* init current environ pointer */
  330.     flag.found = 0;            /* init flag found false        */
  331.     /**
  332.     *        Check each environment string to see if it is the AWDISK
  333.     *        environment string.  The envp array is terminated with
  334.     *        a NULL pointer.  The search is terminated when found is
  335.     *        true or the environment pointer is NULL.
  336.     **/
  337.     while( *cur_envp && !flag.found )
  338.     {
  339.     envid_p = envid;    /* init pointer to our environ id */
  340.     env_chp = *cur_envp;    /* init pointer to environ string */
  341.     flag.found = 1;     /* Set flag found = true to enter loop */
  342.     /**
  343.     *   Compare each character in the string to AWDISK=
  344.     **/
  345.     for ( env_cnt=0; (env_cnt<(sizeof(envid)-1)) && flag.found; env_cnt++)
  346.         {
  347.         if ( *envid_p++ != *env_chp++ )
  348.         flag.found = 0;
  349.         else
  350.         flag.found = 1;
  351.         }
  352.  
  353.     /**
  354.     *   If found true then copy string to our buffer
  355.     *   Replace ';' with 0x00
  356.     *   Count the number of drives found
  357.     *   Set addcwd true to add the current working directory
  358.     **/
  359.     if ( flag.found )
  360.         {
  361.         flag.addcwd = 1;
  362.         /**
  363.         *    Create a duplicate of the environment string
  364.         *    If it cannot be created we will probably fail but allow
  365.         *    continuation just in case
  366.         **/
  367.         if (!(envdup = strdup(env_chp)))
  368.         {
  369.         fprintf( stderr, "Memory alloc problems\n" );
  370.         env_cnt = 0;        /* zero count cause we're goin out   */
  371.         break;            /* allow current drive to continue   */
  372.         }
  373.         /**
  374.         *    Examine the environment string for a ";"
  375.         *    Replace each semicolon with a "\0" to terminate the string
  376.         *    Increment the env_cnt variable for each drive in the system
  377.         *        that the user wished to examine
  378.         *    Place the pointer to the beginning of drive in the envdrv
  379.         *        variable.
  380.         **/
  381.         envd_len = strlen(envdup);    /* get length of environment string  */
  382.         env_cnt  = 0;        /* Set count of drives to zero         */
  383.         env_stp  = envdup;        /* Set the string pointer to current */
  384.         while ( (envd_len > 0) && (env_cnt < MAXEDRV) )
  385.         {
  386.         /**
  387.         *   Look for the semicolon
  388.         **/
  389.         if (env_chp = strchr(env_stp,semicolon))
  390.             {
  391.             /**
  392.             *    We have a semicolon : See if its false
  393.             **/
  394.             if (env_chp-env_stp)
  395.             {
  396.             /**
  397.             *   There is a string so put in array
  398.             *   Decrement the length field
  399.             *   Change the value of the semi colon to a end of str
  400.             *   Set up a new pointer beyond env_stp
  401.             **/
  402.             envdrv[env_cnt++] = env_stp;
  403.             envd_len = envd_len-((env_chp-env_stp)+1);
  404.             *env_chp = end_of_string;
  405.             /**
  406.             *   Check the environment entry against the current
  407.             *    working directory.  If equal set addcwd to
  408.             *    false
  409.             **/
  410.             if ( strcmpi( dos_cwd, env_stp ) == 0 )
  411.                 flag.addcwd = 0;
  412.             env_stp = ++env_chp;
  413.             }
  414.             else
  415.             {
  416.             /**
  417.             *   There was no string just a semicolon
  418.             *   Decrement the length field
  419.             *   setup a new pointer beyond the semi-colon
  420.             **/
  421.             --envd_len;
  422.             env_stp = ++env_chp;
  423.             }
  424.             }
  425.         else
  426.             {
  427.             /**
  428.             *    There was no semi-colon so we are on the last drive
  429.             *        entry.
  430.             *    Place address in array and increment count
  431.             *    Set the remaining string length to zero to exit.
  432.             *    See if last entry matches current working directory
  433.             *        if so don't add it.
  434.             **/
  435.             envdrv[env_cnt++] = env_stp;
  436.             envd_len = 0;
  437.             if ( strcmpi( dos_cwd, env_stp ) == 0 )
  438.             flag.addcwd = 0;
  439.             if ( flag.addcwd )
  440.             {
  441.             if ( (env_cnt < MAXEDRV) && (flag.srchcwd) )
  442.                 envdrv[env_cnt++] = dos_cwd;
  443.             }
  444.             }
  445.         }
  446.         }
  447.     else
  448.         {
  449.         /**
  450.         *    This environment string is not the one we want therefore
  451.         *    Increment current environment pointer and continue
  452.         **/
  453.         cur_envp++;
  454.         }
  455.     }   /* End While */
  456.     }    /* End Else */
  457.  
  458. /**
  459. * The dos_parm is then searched for the last
  460. * occurrence of a backslash to find the end of
  461. * the directory name.
  462. **/
  463.  
  464. last_loc = strrchr(dos_parm,backslash);
  465.  
  466.  
  467. /********************************************************
  468. * If there was not a backslash (and therefore the    *
  469. *     beginning directory is the root directory)    *
  470. * begin                         *
  471. *   copy command line argument into chk_str        *
  472. *   copy root directory into dir_string         *
  473. * end                            *
  474. * else                            *
  475. * (if there was a backslash and therefore a beginning    *
  476. *     directory specified in the command line)        *
  477. * begin                         *
  478. *   set the usr_file to the next character        *
  479. *    past the backslash                *
  480. *   copy the usr_file into chk_str            *
  481. *   copy the command line argument into         *
  482. *    dir_string                    *
  483. *   terminate dir_string just after the         *
  484. *    last backslash (therefore leaving only the    *
  485. *    the directory name in the string)        *
  486. * end                            *
  487. ********************************************************/
  488.  
  489. if (last_loc == NULL)
  490.     {
  491.     /**
  492.     * Since no backslash we'll still check for a drive designator LC 2.14 -JT
  493.     **/
  494.     last_loc = strchr(dos_parm, colon);
  495.     if (last_loc == NULL)
  496.     {
  497.     strcpy(chk_str,dos_parm);
  498.     strcpy(dir_string,"\\");
  499.     }
  500.     else
  501.     {
  502.     usr_file = last_loc + 1;
  503.     strcpy(chk_str,usr_file);
  504.     strcpy(dir_string,dos_parm);
  505.     lst_dchr = usr_file - dos_parm;
  506.     dir_string[lst_dchr++] = backslash;    /* Fake path */
  507.     dir_string[lst_dchr]   = end_of_string; /* terminate directory str */
  508.     }
  509.     }
  510. else
  511.     {
  512.     usr_file = last_loc + 1;
  513.     strcpy(chk_str,usr_file);
  514.     strcpy(dir_string,dos_parm);
  515.     lst_dchr = usr_file - dos_parm;
  516.     dir_string[lst_dchr] = end_of_string;
  517.     }
  518.  
  519.  
  520. /**
  521. *   if the environment string was found concatenate environment drives
  522. *    with the directory string that was extracted.
  523. *   else look for just the directory string
  524. **/
  525.  
  526. if ( flag.found)
  527.     {
  528.     for ( wi = 0; wi < env_cnt; wi++ )
  529.     {
  530.     /**
  531.     *   Search each directory in the environment array
  532.     **/
  533.     strcpy( env_dir_string, envdrv[ wi ] );
  534.     strcat( env_dir_string, dir_string );
  535.     LOOK( env_dir_string );
  536.     }
  537.     }
  538. else
  539.     {
  540.     /**
  541.     *    There is no environment loop so look only for directory string
  542.     **/
  543.     LOOK(dir_string);
  544.     }
  545.  
  546. return;
  547.  
  548. }
  549.  
  550. /**/
  551. /*********************************************************
  552. *    LOOK is the recursive procedure in WHERE     *
  553. *    It is called once for each subdirectory      *
  554. *********************************************************/
  555.  
  556. LOOK(dir_string)
  557. char *dir_string;
  558. {
  559.  
  560. struct DTA cur_DTA;        /* used to return data from DOS  */
  561.  
  562. filename new_dstr;        /* the directory to be         */
  563.                 /* searched on the next      */
  564.                 /* call to LOOK()         */
  565.  
  566. filename cur_str;        /* temporary filename         */
  567.                 /* string for searching for     */
  568.                 /* directories             */
  569.  
  570.  
  571. /**
  572. * Form cur_str by copying dir_string and        *
  573. *    and then concatenating "*.*" to look through all   *
  574. *    files                        *
  575. **/
  576.  
  577. strcpy(cur_str,dir_string);
  578. strcat(cur_str,"*.*");
  579.  
  580. /**
  581. * Set the Disk Transfer Area in DOS to the cur_DTA    *
  582. *    structure                        *
  583. * Get the first subdirectory in this directory        *
  584. **/
  585.  
  586. SET_DTA(&cur_DTA);
  587. GET_FIRST(cur_str,directory_type);
  588.  
  589. /**
  590. * while there are more subdirectories in this directory *
  591. * begin                         *
  592. *   double check for proper directories (see text)    *
  593. *   if a directory                    *
  594. *   begin                        *
  595. *     set up the new_dstr for the            *
  596. *     next call to LOOK (see text)            *
  597. *     call LOOK                     *
  598. *     reset Disk Transfer Address (see text)        *
  599. *   end                         *
  600. *   look for next directory                *
  601. * end                            *
  602. **/
  603.  
  604. while (!(r8086.x.cflag & carry_set))
  605.     {
  606.     if (cur_DTA.DTA_attr == directory_type &&
  607.        cur_DTA.DTA_filename[0] != '.')
  608.     {
  609.     strcpy(new_dstr,dir_string);
  610.     strcat(new_dstr,cur_DTA.DTA_filename);
  611.     strcat(new_dstr,"\\");
  612.     LOOK(new_dstr);
  613.     SET_DTA(&cur_DTA);
  614.     }
  615.     GET_NEXT();
  616.     }
  617.  
  618. /********************************************************
  619. * if there are no more subdirectories in this directory *
  620. *   look for files                    *
  621. * else                            *
  622. *   print an error message                *
  623. ********************************************************/
  624.  
  625. if (r8086.x.ax == no_more_files)
  626.     GET_FILES(dir_string,&cur_DTA);
  627. else
  628.     printf("problem with looking thru %s\n",dir_string);
  629. return;
  630.  
  631. }
  632.  
  633.  
  634. /********************************************************
  635. * GET_FILES                        *
  636. * is called once per directory to look for the        *
  637. *   actual files matching the search string        *
  638. ********************************************************/
  639.  
  640. GET_FILES(dir_string,cur_DTA)
  641. char *dir_string;
  642. struct DTA *cur_DTA;
  643. {
  644.  
  645. filename cur_str;
  646.  
  647. /********************************************************
  648. * Form cur_str by copying dir_string into  *
  649. *   it and then concatenating the chk_str onto       *
  650. *   the end                        *
  651. ********************************************************/
  652.  
  653. strcpy(cur_str,dir_string);
  654. strcat(cur_str,chk_str);
  655.  
  656. /*********************************************************
  657. * Get the first file that matches cur_str     *
  658. ********************************************************/
  659.  
  660. GET_FIRST(cur_str,no_type);
  661.  
  662. /********************************************************
  663. * while there are more files that match the search    *
  664. *   string:                        *
  665. * begin                         *
  666. *   print the file information                *
  667. *   get the next file                    *
  668. * end                            *
  669. ********************************************************/
  670.  
  671. while (!(r8086.x.cflag & carry_set))
  672.     {
  673.     printf(" %10ld %s  %s%s\n", (*cur_DTA).DTA_size,
  674.        DATE(&((*cur_DTA).DTA_date)), dir_string,
  675.        (*cur_DTA).DTA_filename);
  676.     GET_NEXT();
  677.     }
  678.  
  679. /*********************************************************
  680. * if error in looking for a file            *
  681. *    print error message and return            *
  682. ********************************************************/
  683.  
  684. if (r8086.x.ax != no_more_files)
  685.     printf("problem with looking for %s\n",cur_str);
  686.  
  687. return;
  688.  
  689. }
  690.  
  691. /********************************************************
  692. * GET_NEXT does an interrupt 21h, function 4Fh        *
  693. * Function 4fh is Get next directory entry        *
  694. ********************************************************/
  695.  
  696. GET_NEXT()
  697.  
  698. {
  699. r8086.x.ax = 0x4f00;
  700.  
  701. dos_result = int86x( 0x21, &r8086, &r8086, &s8086 );
  702.  
  703. return;
  704. }
  705.  
  706.  
  707. /********************************************************
  708. * SET_DTA does an interrupt 21h, function 1Ah        *
  709. *   The DS:DX pair is set to the address of the     *
  710. *   cur_DTA data structure                *
  711. ********************************************************/
  712.  
  713. SET_DTA(cur_DTA)
  714. struct DTA    *cur_DTA;
  715. {
  716.  
  717. r8086.x.ax = 0x1a00;
  718. r8086.x.dx = (int)cur_DTA;        /* set offset to disk transfer area */
  719.  
  720. dos_result = int86x(0x21, &r8086, &r8086, &s8086 );
  721.  
  722. return;
  723.  
  724. }
  725.  
  726. /********************************************************
  727. * GET_FIRST does an interrupt 21h, function 4Eh     *
  728. *   The CX register is set to either normal or        *
  729. *   directory type (see text)                *
  730. *   The DS:DX pair is set to the address of the     *
  731. *   search string                    *
  732. ********************************************************/
  733.  
  734. GET_FIRST(sea_str,filetype)
  735. char *sea_str;
  736. int filetype;
  737. {
  738.  
  739. r8086.x.ax = 0x4e00;                /* Set DOS function     */
  740. r8086.x.cx = filetype;                /* Set search attributes */
  741. r8086.x.dx = (int)    sea_str;          /* Set address of string */
  742.  
  743. dos_result = int86x( 0x21, &r8086, &r8086, &s8086 );
  744.  
  745. return;
  746.  
  747. }
  748.  
  749. /********************************************************
  750. * DATE takes the date field from the current DTA    *
  751. *   structure and returns a string containing the    *
  752. *   information in formatted ASCII            *
  753. ********************************************************/
  754.  
  755. char *DATE(dateptr)
  756. struct msdos_date *dateptr;
  757. {
  758.  
  759. sprintf(date_str, "%02d-%02d-%02d %02d:%02d %s",
  760.     dateptr->ms_month, dateptr->ms_day,
  761.     dateptr->ms_year+80, (dateptr->ms_hour)%12,
  762.     dateptr->ms_min, time_of_day[((dateptr->ms_hour)/12)]);
  763. return(date_str);
  764.  
  765. }
  766.